<template>
    <div class="panel-tab__content">
        <!-- 监听器表格 -->
        <base-table
            ref="elementListeners"
            :tableData="elementListenersTableConfig.tableData"
            :tableHeader="elementListenersTableConfig.tableHeader"
            :tableConfig="elementListenersTableConfig.tableConfig"
        >
            <template slot-scope="{ scope }">
                <span v-if="scope.type === 'index'">
                    {{ scope.$index + 1 }}
                </span>
                <span v-if="scope.type === 'listenerType'">
                    {{ listenerTypeObject[scope.row.listenerType] }}
                </span>
                <div v-if="scope.type === 'handle'">
                    <el-button
                        size="mini"
                        type="text"
                        @click="openListenerForm(scope.row, scope.$index)"
                        >编辑</el-button
                    >
                    <el-divider direction="vertical" />
                    <el-button
                        size="mini"
                        type="text"
                        style="color: #ff4d4f"
                        @click="removeListener(scope.row, scope.$index)"
                        >移除</el-button
                    >
                </div>
            </template>
        </base-table>
        <div class="element-drawer__button">
            <el-button
                size="mini"
                type="primary"
                icon="el-icon-plus"
                @click="openListenerForm(null)"
                >添加监听器</el-button
            >
        </div>
        <!-- 监听器 编辑/创建 部分 -->
        <el-drawer
            :visible.sync="listenerFormModelVisible"
            title="执行监听器"
            :size="`${width}px`"
            append-to-body
            destroy-on-close
        >
            <div class="drawer-contener">
                <!-- 监听器表单 -->
                <base-form
                    :formItems="listenerFormConfig.formItems"
                    :formData="listenerFormConfig.formSubmit"
                    :formConfig="listenerFormConfig.formConfig"
                    :formRules="listenerFormConfig.formRule"
                    @onSelectChange="updateListenerForm"
                    ref="listenerForm"
                />
                <template slot="footer">
                    <el-button size="mini" @click="modelVisible = false"
                        >取 消</el-button
                    >
                    <el-button
                        size="mini"
                        type="primary"
                        @click="saveListenerConfig"
                        >保 存</el-button
                    >
                </template>
                <el-divider />
                <p class="listener-filed__title">
                    <span><i class="el-icon-menu"></i>注入字段：</span>
                    <el-button
                        size="mini"
                        type="primary"
                        @click="openFieldForm(null)"
                        >添加字段</el-button
                    >
                </p>
                <!-- 注入器表格 -->
                <base-table
                    ref="fieldsListOfListener"
                    :tableData="fieldsListenerTableConfig.tableData"
                    :tableHeader="fieldsListenerTableConfig.tableHeader"
                    :tableConfig="fieldsListenerTableConfig.tableConfig"
                >
                    <template slot-scope="{ scope }">
                        <span v-if="scope.type === 'index'">
                            {{ scope.$index + 1 }}
                        </span>
                        <span v-if="scope.type === 'fieldType'">
                            {{ fieldTypeObject[scope.row.fieldType] }}
                        </span>
                        <span v-if="scope.type === 'expression'">
                            {{ scope.row.string || scope.row.expression }}
                        </span>
                        <div v-if="scope.type === 'handle'">
                            <el-button
                                size="mini"
                                type="text"
                                @click="openFieldForm(scope.row, scope.$index)"
                                >编辑</el-button
                            >
                            <el-divider direction="vertical" />
                            <el-button
                                size="mini"
                                type="text"
                                style="color: #ff4d4f"
                                @click="
                                    removeListenerField(scope.row, scope.$index)
                                "
                                >移除</el-button
                            >
                        </div>
                    </template>
                </base-table>
                <el-divider />
                <div class="element-drawer__button">
                    <el-button
                        size="mini"
                        @click="listenerFormModelVisible = false"
                        >取 消</el-button
                    >
                    <el-button
                        size="mini"
                        type="primary"
                        @click="saveListenerConfig"
                        >保 存</el-button
                    >
                </div>
            </div>
        </el-drawer>

        <!-- 注入西段 编辑/创建 部分 -->
        <el-dialog
            title="字段配置"
            :visible.sync="listenerFieldFormModelVisible"
            width="600px"
            append-to-body
            destroy-on-close
        >
            <!-- 注入器表单 -->
            <base-form
                :formItems="fieldFormConfig.formItems"
                :formData="fieldFormConfig.formSubmit"
                :formConfig="fieldFormConfig.formConfig"
                :formRules="fieldFormConfig.formRule"
                ref="fieldForm"
                @onSelectChange="updatefieldForm"
            />
            <template slot="footer">
                <el-button
                    size="mini"
                    @click="listenerFieldFormModelVisible = false"
                    >取 消</el-button
                >
                <el-button size="mini" type="primary" @click="saveListenerFiled"
                    >确 定</el-button
                >
            </template>
        </el-dialog>
    </div>
</template>
<script>
import { createListenerObject, updateElementExtensions } from '../../utils'
import {
    initListenerType,
    initListenerForm,
    listenerType,
    fieldType
} from './utilSelf'
import { setFormItemProp } from '@/utils/tool'
import BaseTable from '@/components/baseTable/index'
import BaseForm from '@/components/baseForm/index'
const listenerTypeOptions = () => {
    let options = []
    for (const key in listenerType) {
        if (Object.hasOwnProperty.call(listenerType, key)) {
            const element = {
                label: listenerType[key],
                value: key
            }
            options.push(element)
        }
        console.log('options', options)
    }
    return options
}
const fieldTypeOptions = () => {
    let options = []
    for (const key in fieldType) {
        if (Object.hasOwnProperty.call(fieldType, key)) {
            const element = {
                label: fieldType[key],
                value: key
            }
            options.push(element)
        }
    }
    return options
}
export default {
    name: 'ElementListeners',
    components: {
        BaseTable,
        BaseForm
    },
    props: {
        id: String,
        type: String
    },
    inject: {
        prefix: 'prefix',
        width: 'width'
    },
    data() {
        return {
            listenerFormModelVisible: false, // 监听器 编辑 侧边栏显示状态
            // 监听器表格
            elementListenersTableConfig: {
                // 表格数据
                tableData: [],
                // 表格头数据
                tableHeader: [
                    {
                        type: 'index',
                        label: '序号',
                        width: 50,
                        visible: true
                    },
                    {
                        prop: 'event',
                        label: '事件类型',
                        visible: true,
                        showOverflowTooltip: true
                    },
                    {
                        type: 'listenerType',
                        label: '监听器类型',
                        visible: true,
                        showOverflowTooltip: true
                    },
                    {
                        label: '操作',
                        type: 'handle',
                        visible: true
                    }
                ],
                // 表格配置
                tableConfig: {
                    border: true,
                    size: 'mini',
                    height: 'auto'
                }
            },
            // 监听器详情表单
            listenerFormConfig: {
                formItems: [
                    [
                        {
                            ltype: 'select',
                            placeholder: '请输入事件类型',
                            label: '事件类型',
                            prop: 'event',
                            options: [
                                {
                                    label: 'start',
                                    value: 'start'
                                },
                                {
                                    label: 'end',
                                    value: 'end'
                                }
                            ],
                            width: 'w-1',
                            isShow: true
                        }
                    ],
                    [
                        {
                            ltype: 'select',
                            placeholder: '请输入监听器类型',
                            label: '监听器类型',
                            prop: 'listenerType',
                            options: listenerTypeOptions(),
                            width: 'w-1',
                            isShow: true
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入Java类',
                            label: 'Java类',
                            prop: 'class',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入表达式',
                            label: '表达式',
                            prop: 'expression',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入代理表达式',
                            label: '代理表达式',
                            prop: 'delegateExpression',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请填写脚本格式',
                            label: '脚本格式',
                            prop: 'scriptFormat',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'select',
                            placeholder: '请选择脚本类型',
                            label: '脚本类型',
                            prop: 'scriptType',
                            width: 'w-1',
                            options: [
                                {
                                    lable: '内联脚本',
                                    value: 'inlineScript'
                                },
                                {
                                    lable: '外部脚本',
                                    value: 'externalScript'
                                }
                            ],
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请填写脚本内容',
                            label: '脚本内容',
                            prop: 'value',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请填写资源地址',
                            label: '资源地址',
                            prop: 'resource',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ]
                ],
                formSubmit: {
                    //事件类型
                    event: '',
                    // 监听器类型
                    listenerType: '',
                    // java类
                    class: '',
                    // 表达式
                    expression: '',
                    // 代理表达式
                    delegateExpression: '',
                    // 脚本格式
                    scriptFormat: '',
                    // 脚本类型
                    scriptType: '',
                    // 脚本内容
                    value: '',
                    // 资源地址
                    resource: '',
                    fields: []
                },
                formConfig: {
                    labelPosition: 'left', // label对齐方式
                    labelWidth: '100px',
                    size: 'mini',
                    height: 'auto'
                },
                formRule: {
                    event: [
                        {
                            required: true,
                            trigger: ['blur', 'change']
                        }
                    ],
                    listenerType: [
                        {
                            required: true,
                            trigger: ['blur', 'change']
                        }
                    ],
                    class: [
                        {
                            required: true,
                            message: '请输入Java类',
                            trigger: ['blur', 'change']
                        }
                    ],
                    expression: [
                        {
                            required: true,
                            message: '请填写表达式',
                            trigger: ['blur', 'change']
                        }
                    ],
                    delegateExpression: [
                        {
                            required: true,
                            message: '请填写代理表达式',
                            trigger: ['blur', 'change']
                        }
                    ],
                    scriptFormat: [
                        {
                            required: true,
                            message: '请填写脚本格式',
                            trigger: ['blur', 'change']
                        }
                    ],
                    scriptType: [
                        {
                            required: true,
                            message: '请选择脚本类型',
                            trigger: ['blur', 'change']
                        }
                    ],
                    value: [
                        {
                            required: true,
                            message: '请填写脚本内容',
                            trigger: ['blur', 'change']
                        }
                    ],
                    resource: [
                        {
                            required: true,
                            message: '请填写资源地址',
                            trigger: ['blur', 'change']
                        }
                    ]
                }
            },
            // 注入的表格配置
            fieldsListenerTableConfig: {
                // 表格数据
                tableData: [],
                // 表格头数据
                tableHeader: [
                    {
                        type: 'index',
                        label: '序号',
                        width: 50,
                        visible: true
                    },
                    {
                        prop: 'name',
                        label: '字段名称',
                        visible: true,
                        showOverflowTooltip: true
                    },
                    {
                        type: 'fieldType',
                        label: '字段类型',
                        visible: true,
                        showOverflowTooltip: true
                    },
                    {
                        type: 'expression',
                        label: '字段值/表达式',
                        visible: true,
                        showOverflowTooltip: true
                    },
                    {
                        label: '操作',
                        type: 'handle',
                        visible: true
                    }
                ],
                // 表格配置
                tableConfig: {
                    border: true,
                    size: 'mini',
                    height: 'auto'
                }
            },
            // 注入的表单配置
            fieldFormConfig: {
                formItems: [
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入字段名称',
                            label: '字段名称',
                            prop: 'name',
                            width: 'w-1',
                            isShow: true
                        }
                    ],
                    [
                        {
                            ltype: 'select',
                            placeholder: '请选择字段类型',
                            label: '字段类型',
                            prop: 'fieldType',
                            options: fieldTypeOptions(),
                            width: 'w-1',
                            isShow: true
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入字段值',
                            label: '字段值',
                            prop: 'string',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ],
                    [
                        {
                            ltype: 'input',
                            placeholder: '请输入表达式',
                            label: '表达式',
                            prop: 'expression',
                            width: 'w-1',
                            clearable: true,
                            isShow: false
                        }
                    ]
                ],
                formSubmit: {
                    //字段名称
                    name: '',
                    // 字段类型
                    fieldType: '',
                    // 字段值
                    string: '',
                    // 表达式
                    expression: ''
                },
                formConfig: {
                    labelPosition: 'left', // label对齐方式
                    labelWidth: '100px',
                    size: 'mini',
                    height: 'auto'
                },
                formRule: {
                    name: [
                        {
                            required: true,
                            message: '请输入字段名称',
                            trigger: ['blur', 'change']
                        }
                    ],
                    fieldType: [
                        {
                            required: true,
                            message: '请选择字段类型',
                            trigger: ['blur', 'change']
                        }
                    ],
                    string: [
                        {
                            required: true,
                            message: '请输入字段值',
                            trigger: ['blur', 'change']
                        }
                    ],
                    expression: [
                        {
                            required: true,
                            message: '请填写表达式',
                            trigger: ['blur', 'change']
                        }
                    ]
                }
            },
            listenerFieldForm: {}, // 监听器 注入字段 详情表单
            listenerFieldFormModelVisible: false, // 监听器 注入字段表单弹窗 显示状态
            editingListenerIndex: -1, // 监听器所在下标，-1 为新增
            editingListenerFieldIndex: -1, // 字段所在下标，-1 为新增
            listenerTypeObject: listenerType,
            fieldTypeObject: fieldType
        }
    },
    watch: {
        id: {
            immediate: true,
            handler(val) {
                val &&
                    val.length &&
                    this.$nextTick(() => this.resetListenersList())
            }
        }
    },
    methods: {
        // 修改监听器表单的显示项
        updateListenerForm() {
            this.$nextTick(() => {
                const changeItem = [
                    'class',
                    'expression',
                    'delegateExpression',
                    'scriptFormat',
                    'scriptType',
                    'value',
                    'resource'
                ]
                changeItem.filter(key => {
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        key,
                        'isShow',
                        false
                    )
                    this.listenerFormConfig.formRule[key][0].required = false
                })
                if (
                    this.listenerFormConfig.formSubmit.listenerType ===
                    'classListener'
                ) {
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        'class',
                        'isShow',
                        true
                    )
                    this.listenerFormConfig.formRule['class'][0].required = true
                } else if (
                    this.listenerFormConfig.formSubmit.listenerType ===
                    'expressionListener'
                ) {
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        'expression',
                        'isShow',
                        true
                    )
                    this.listenerFormConfig.formRule[
                        'expression'
                    ][0].required = true
                } else if (
                    this.listenerFormConfig.formSubmit.listenerType ===
                    'delegateExpressionListener'
                ) {
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        'delegateExpression',
                        'isShow',
                        true
                    )
                    this.listenerFormConfig.formRule[
                        'delegateExpression'
                    ][0].required = true
                } else if (
                    this.listenerFormConfig.formSubmit.listenerType ===
                    'scriptListener'
                ) {
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        'scriptFormat',
                        'isShow',
                        true
                    )
                    setFormItemProp(
                        this.listenerFormConfig.formItems,
                        'scriptType',
                        'isShow',
                        true
                    )
                    this.listenerFormConfig.formRule[
                        'scriptFormat'
                    ][0].required = true
                    this.listenerFormConfig.formRule[
                        'scriptType'
                    ][0].required = true
                    if (
                        this.listenerFormConfig.formSubmit.scriptType ===
                        'inlineScript'
                    ) {
                        setFormItemProp(
                            this.listenerFormConfig.formItems,
                            'value',
                            'isShow',
                            true
                        )
                        this.listenerFormConfig.formRule[
                            'value'
                        ][0].required = true
                    } else if (
                        this.listenerFormConfig.formSubmit.scriptType ===
                        'externalScript'
                    ) {
                        setFormItemProp(
                            this.listenerFormConfig.formItems,
                            'resource',
                            'isShow',
                            true
                        )
                        this.listenerFormConfig.formRule[
                            'resource'
                        ][0].required = true
                    }
                }
            })
        },
        // 修改注入表单的现实项
        updatefieldForm() {
            this.$nextTick(() => {
                setFormItemProp(
                    this.fieldFormConfig.formItems,
                    'string',
                    'isShow',
                    false
                )
                setFormItemProp(
                    this.fieldFormConfig.formItems,
                    'expression',
                    'isShow',
                    false
                )
                this.fieldFormConfig.formRule['string'][0].required = false
                this.fieldFormConfig.formRule['expression'][0].required = false
                if (this.fieldFormConfig.formSubmit.fieldType === 'string') {
                    setFormItemProp(
                        this.fieldFormConfig.formItems,
                        'string',
                        'isShow',
                        true
                    )
                    this.fieldFormConfig.formRule['string'][0].required = true
                } else if (
                    this.fieldFormConfig.formSubmit.fieldType === 'expression'
                ) {
                    setFormItemProp(
                        this.fieldFormConfig.formItems,
                        'expression',
                        'isShow',
                        true
                    )
                    this.fieldFormConfig.formRule[
                        'expression'
                    ][0].required = true
                }
            })
        },
        // 初始化监听表单的显示项
        initListenerForm(values) {
            if (values) {
                this.listenerFormConfig.formSubmit = this.$_.cloneDeep(values)
            } else {
                this.listenerFormConfig.formSubmit = {
                    //事件类型
                    event: '',
                    // 监听器类型
                    listenerType: '',
                    // java类
                    class: '',
                    // 表达式
                    expression: '',
                    // 代理表达式
                    delegateExpression: '',
                    // 脚本格式
                    scriptFormat: '',
                    // 脚本类型
                    scriptType: '',
                    // 脚本内容
                    value: '',
                    // 资源地址
                    resource: '',
                    // 注入列表
                    fields: []
                }
            }
        },
        // 初始化注入表单的显示项
        initFieldForm(values) {
            if (values) {
                this.fieldFormConfig.formSubmit = this.$_.cloneDeep(values)
            } else {
                this.fieldFormConfig.formSubmit = {
                    //字段名称
                    name: '',
                    // 字段类型
                    fieldType: '',
                    // 字段值
                    string: '',
                    // 表达式
                    expression: ''
                }
            }
            console.log(
                'this.fieldFormConfig.formSubmit',
                this.fieldFormConfig.formSubmit
            )
        },
        resetListenersList() {
            this.bpmnElement = window.bpmnInstances.bpmnElement
            this.otherExtensionList = []
            this.bpmnElementListeners =
                this.bpmnElement.businessObject?.extensionElements?.values?.filter(
                    ex => ex.$type === `${this.prefix}:ExecutionListener`
                ) ?? []
            this.elementListenersTableConfig.tableData = this.bpmnElementListeners.map(
                listener => initListenerType(listener)
            )
        },
        // 打开 监听器详情 侧边栏
        openListenerForm(listener, index) {
            if (listener) {
                this.listenerFormConfig.formSubmit = initListenerForm(listener)
                this.initListenerForm(listener)
                this.editingListenerIndex = index
            } else {
                this.initListenerForm()
                this.editingListenerIndex = -1 // 标记为新增
            }
            if (listener && listener.fields) {
                this.fieldsListenerTableConfig.tableData = listener.fields.map(
                    field => ({
                        ...field,
                        fieldType: field.string ? 'string' : 'expression'
                    })
                )
            } else {
                this.fieldsListenerTableConfig.tableData = []
                this.$set(this.listenerFormConfig.formSubmit, 'fields', [])
            }
            // 打开侧边栏并清楚验证状态
            this.listenerFormModelVisible = true
            this.$nextTick(() => {
                if (this.$refs['listenerForm'])
                    this.$refs['listenerForm'].resetForm()
            })
        },
        // 打开监听器字段编辑弹窗
        openFieldForm(field, index) {
            console.log('field', field)
            console.log('index', index)
            this.initFieldForm(field)
            this.editingListenerFieldIndex = field ? index : -1
            this.listenerFieldFormModelVisible = true
            if (!field) {
                this.$nextTick(() => {
                    if (this.$refs['fieldForm'])
                        this.$refs['fieldForm'].resetForm()
                })
            }
        },
        // 保存监听器注入字段
        saveListenerFiled() {
            this.$refs['fieldForm'].submitForm(res => {
                if (res) {
                    if (this.editingListenerFieldIndex === -1) {
                        this.fieldsListenerTableConfig.tableData.push(
                            this.fieldFormConfig.formSubmit
                        )
                        this.listenerFormConfig.formSubmit.fields.push(
                            this.fieldFormConfig.formSubmit
                        )
                    } else {
                        this.fieldsListenerTableConfig.tableData.splice(
                            this.editingListenerFieldIndex,
                            1,
                            this.fieldFormConfig.formSubmit
                        )
                        this.listenerFormConfig.formSubmit.fields.splice(
                            this.editingListenerFieldIndex,
                            1,
                            this.fieldFormConfig.formSubmit
                        )
                    }
                    this.listenerFieldFormModelVisible = false
                    this.$nextTick(() => this.initFieldForm())
                } else {
                    return false
                }
            })
            // this.$refs['listenerForm'].resetForm();
            // console.log('validateStatus', validateStatus)
            // if (!validateStatus) return // 验证不通过直接返回
        },
        // 移除监听器字段
        removeListenerField(field, index) {
            this.$confirm('确认移除该字段吗？', '提示', {
                confirmButtonText: '确 认',
                cancelButtonText: '取 消'
            })
                .then(() => {
                    this.fieldsListenerTableConfig.tableData.splice(index, 1)
                    this.listenerFormConfig.formSubmit.fields.splice(index, 1)
                })
                .catch(() => console.info('操作取消'))
        },
        // 移除监听器
        removeListener(listener, index) {
            this.$confirm('确认移除该监听器吗？', '提示', {
                confirmButtonText: '确 认',
                cancelButtonText: '取 消'
            })
                .then(() => {
                    this.bpmnElementListeners.splice(index, 1)
                    this.elementListenersTableConfig.tableData.splice(index, 1)
                    updateElementExtensions(
                        this.bpmnElement,
                        this.otherExtensionList.concat(
                            this.bpmnElementListeners
                        )
                    )
                })
                .catch(() => console.info('操作取消'))
        },
        // 保存监听器配置
        saveListenerConfig() {
            this.$refs['listenerForm'].submitForm(res => {
                if (res) {
                    const listenerObject = createListenerObject(
                        this.listenerFormConfig.formSubmit,
                        false,
                        this.prefix
                    )
                    if (this.editingListenerIndex === -1) {
                        this.bpmnElementListeners.push(listenerObject)
                        this.elementListenersTableConfig.tableData.push(
                            this.listenerFormConfig.formSubmit
                        )
                    } else {
                        this.bpmnElementListeners.splice(
                            this.editingListenerIndex,
                            1,
                            listenerObject
                        )
                        this.elementListenersTableConfig.tableData.splice(
                            this.editingListenerIndex,
                            1,
                            this.listenerFormConfig.formSubmit
                        )
                    }
                    // 保存其他配置
                    this.otherExtensionList =
                        this.bpmnElement.businessObject?.extensionElements?.values?.filter(
                            ex =>
                                ex.$type !== `${this.prefix}:ExecutionListener`
                        ) ?? []
                    updateElementExtensions(
                        this.bpmnElement,
                        this.otherExtensionList.concat(
                            this.bpmnElementListeners
                        )
                    )
                    // 4. 隐藏侧边栏
                    this.listenerFormModelVisible = false
                    this.initListenerForm()
                } else {
                    return
                }
            })
        }
    }
}
</script>
<style lang="scss">
.drawer-contener {
    padding: 0 $margin-md;
}
.fieldform-contener {
    padding-bottom: $margin-md;
}
</style>
